package com.cskaoyan.javase.oop2._1extends._10final._3variable._2member;

/**
 * final修饰成员变量,表示成员常量,表示该成员变量的取值不可变,但其它的并不改变.
 * 语法:
 *      [访问权限修饰符] final 数据类型 变量名;
 *
 * 解释:
 *      1.成员变量具有默认初始化,无需程序员手动初始化
 *          但是很明显final修饰的成员变量,没有默认初始化了,必须手动初始化
 *          (既然是常量就肯定只能赋值一次,然后就不可变了,如果还有默认初始化就不合理了)
 *
 *      2.现在,排除默认初始化,给对象的成员变量赋值的手段还有:
 *          a.显式赋值
 *          b.构造器赋值
 *          c.构造代码块赋值
 *       以上三种赋值方式,必须选择其一,且只能选择其一.
 *
 *
 *       3.(细节)
 *       如果用构造器给某个成员常量赋值,要注意
 *       必须每个构造器都要满足赋值(因为一个构造器就是一种new对象的方式)
 *
 * 思考:  所谓的成员常量,是不是一个真正意义上的常量?
 *      很明显,成员常量仍然是属于对象的
 *      不同对象之间,成员常量的取值,完全可以不同
 *      所以成员常量并不是一个真正意义上的常量
 *      在实际开发中,我们往往需要一个真正意义上的常量,那怎么办呢?
 *      就是final修饰的静态成员变量,它是final最常用的场景.
 *
 *
 * @since 17:11
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student("蔡徐坤");
        System.out.println(s.name);
        System.out.println(s.age);
        System.out.println(s.score);
        // s.name = "肖战";
        // s.age = 28;

        Student s2 = new Student("肖战");
        System.out.println(s2.name);
    }
}

class Student {
    // Variable 'age' might not have been initialized
    final int age = 18;
    final double score;
    final String name;

    {
        // age = 28;
        score = 100;
    }
    public Student(){
        name = "长风";
    }

    public Student(String name) {
        this.name = name;
    }
}